package com.utils;

import com.graphics.ImageIdentity;
import com.utils.generated.*;
import com.utils.generated.ObjectFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.ListIterator;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import mapgenerator.Main;

/**
 *
 * @author Sajarwo Anggai
 */
public class MapOperation {

    private JAXBContext jc;
    private Project project;
    private ImageManager im;
    private ImagePattern ip;
    private ObjectSprite os;
    private Main comp;

    public MapOperation(Main comp) {
        try {
            this.comp = comp;
            jc = JAXBContext.newInstance(ObjectFactory.class);
        } catch (JAXBException ex) {
        }
    }

    public void openMap(String location) {
        try {
            Unmarshaller u = jc.createUnmarshaller();
            Map map = (Map) u.unmarshal(new File(location));
            List list = (List) map.getObjectSpriteOrImagePatternOrImageManagerOrProject();
            ListIterator itr = list.listIterator(0);
            while (itr.hasNext()) {
                Object ob = itr.next();
                if (ob instanceof Project) {
                    project = (Project) ob;
                } else if (ob instanceof ImageManager) {
                    im = (ImageManager) ob;
                } else if (ob instanceof ImagePattern) {
                    ip = (ImagePattern) ob;
                } else if (ob instanceof ObjectSprite) {
                    os = (ObjectSprite) ob;
                }
            }            
            loadProject(false);
            loadImageManager(false);
            loadPattern(false);
            loadObjectSprite(false);
        } catch (JAXBException ex) {
            System.out.println("Eror occured at Loading XML");
        }
    }

    public void saveMap(String location) {
        try {
            ObjectFactory factory = new ObjectFactory();
            Map map = factory.createMap();
            project = factory.createProject();
            im = factory.createImageManager();
            ip = factory.createImagePattern();
            os = factory.createObjectSprite();

            loadProject(true);
            loadImageManager(true);
            loadPattern(true);
            loadObjectSprite(true);
            map.getObjectSpriteOrImagePatternOrImageManagerOrProject().add(project);
            map.getObjectSpriteOrImagePatternOrImageManagerOrProject().add(im);
            map.getObjectSpriteOrImagePatternOrImageManagerOrProject().add(ip);
            map.getObjectSpriteOrImagePatternOrImageManagerOrProject().add(os);

            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(map, new FileOutputStream(location));

        } catch (Exception ex) {
            System.out.println("Error occured at Saving XML" + ex);
        }
    }

    public void loadProject(boolean save) {
        if (save) {
            project.setName(comp.project.getProjectName());
            project.setProjectDir(comp.project.getPath());
            project.setImageDir(comp.project.getImageDir());
            project.setMapWidth("" + comp.project.getMapWidth());
            project.setMapHeigh("" + comp.project.getMapHeight());
            project.setTileWidth("" + comp.project.getTileWidth());
            project.setTileHeight("" + comp.project.getTileHeight());
        } else {
            comp.project.setPath(project.getProjectDir());
            comp.project.setImageDir(project.getImageDir());
            System.out.println("XML imdir"+project.getImageDir());
            comp.project.setMapWidth(Integer.parseInt(project.getMapWidth()));
            comp.project.setMapHeight(Integer.parseInt(project.getMapHeigh()));
            comp.project.setTileWidth(Integer.parseInt(project.getTileWidth()));
            comp.project.setTileHeight(Integer.parseInt(project.getTileHeight()));
        }
    }

    private void loadImageManager(boolean save) {
        List list;
        if (save) {
            list = comp.imContainer.getImages();
            for (int i = 0; i < list.size(); i++) {
                Image img = new Image();
                img.setName("" + list.get(i));
                im.getImage().add(img);
            }
        } else {
            list = im.getImage();
            for (int i = 0; i < list.size(); i++) {
                comp.imContainer.addImage(((Image) list.get(i)).getName());
            }
        }
    }

    public void loadPattern(boolean save) {
        List list;
        if (save) {
            list = comp.ipContainer.getListImagePattern();
            for (int i = 0; i < list.size(); i++) {
                ImageIdentity imageIdentity = (ImageIdentity) list.get(i);
                Pattern p = new Pattern();
                p.setName(imageIdentity.getName());
                p.setRows("" + imageIdentity.getRows());
                p.setCols("" + imageIdentity.getCols());
                p.setIsSprite(imageIdentity.isSprite() ? "0" : "1");
                ip.getPattern().add(p);
            }
        } else {
            list = ip.getPattern();
            for (int i = 0; i < list.size(); i++) {
                Pattern p = (Pattern) list.get(i);
                comp.ipContainer.addImage(p.getName(), Integer.parseInt(p.getRows()), Integer.parseInt(p.getCols()), p.getIsSprite().equals("0") ? true : false);
            }
        }
    }

    public void loadObjectSprite(boolean save) {
        List list;
        if (save) {
            list = comp.osContainer.getSprites();
            System.out.println("sprite");
            for (int i = 0; i < list.size(); i++) {
                com.os.ObjectSprite obSprite = (com.os.ObjectSprite) list.get(i);
                Sprite s = new Sprite();
                s.setName(obSprite.getName());
                System.out.println("sprite" + i);
                s.setIsCharacter(obSprite.isCharacter() ? "0" : "1");
                if (obSprite.isCharacter()) {
                    if (obSprite.getLeft() != null) {
                        s.setLeft(obSprite.getLeft().getName());
                    }
                    if (obSprite.getRight() != null) {
                        s.setRigh(obSprite.getRight().getName());
                    }
                    if (obSprite.getUp() != null) {
                        s.setUp(obSprite.getUp().getName());
                    }
                    if (obSprite.getDown() != null) {
                        s.setDown(obSprite.getDown().getName());
                    }
                } else if (obSprite.getOther() != null) {
                    s.setOther(obSprite.getOther().getName());
                }
                os.getSprite().add(s);
            }
        } else {
            list = os.getSprite();
            for (int i = 0; i < list.size(); i++) {
                Sprite p = (Sprite) list.get(i);
                com.os.ObjectSprite obSprite = new com.os.ObjectSprite(p.getName());
                obSprite.setName(p.getName());
                obSprite.setCharacter(p.getIsCharacter().equals("0"));
                if (p.getIsCharacter().equals("0")) {
                    obSprite.setLeft(comp.ipContainer.getPattern(p.getLeft()));
                    obSprite.setRight(comp.ipContainer.getPattern(p.getRigh()));
                    obSprite.setUp(comp.ipContainer.getPattern(p.getUp()));
                    obSprite.setDown(comp.ipContainer.getPattern(p.getDown()));
                } else {
                    obSprite.setOther(comp.ipContainer.getPattern(p.getOther()));
                }
                comp.osContainer.addSprites(obSprite);
            }
        }
    }
}
